package pro.cherish.knowledgeutil.bean;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import lombok.extern.slf4j.Slf4j;
import pro.cherish.knowledgeutil.common.ObjectUtilExt;
import pro.cherish.knowledgeutil.json.JsonUtilExt;
import pro.cherish.knowledgeutil.str.StringUtilExt;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 创建人：cherish
 * @version 版本号：V1.0
 * <p>
 * ***************************修订记录************************************
 * 2019-11-01 cherish 创建该类功能。
 * **********************************************************************
 * </p>
 * @ClassName 类名：BeanUtilExt
 * @Description 功能说明：
 * <p>
 * TODO
 * </p>
 * **********************************************************************
 * @date 创建日期： 2019-11-01 cherish
 */
@Slf4j
public class BeanUtilExt extends BeanUtil {

    /**
     * 获取对象中部分属性的值，值都是字符串形式
     *
     * @param srcObj     源对象
     * @param properties 属性名
     * @return
     */
    public static String[] getFieldValues(Object srcObj, String[] properties) {
        String[] result = new String[properties.length];
        for (int i = 0; i < properties.length; i++) {
            result[i] = StringUtilExt.toString(getFieldValue(srcObj, properties[i]));
        }
        return result;
    }

    /**
     * 对象转为map
     * 注意：对象为null则转为空Map
     *
     * @param obj 源对象
     * @return
     */
    public static Map<String, Object> objectKeyNullToEmpty(Object obj) {
        //暂时先用gson转json 然后转成Map对象 xds20170323
        if (ObjectUtilExt.isEmpty(obj)) {
            return new HashMap<String, Object>();
        }
        return JsonUtilExt.json2Map(JsonUtilExt.toJsonString(obj));
    }

    /**
     * 对象转为map
     * 注意：对象为null则转为空Map，同时key转为驼峰
     *
     * @param obj 源对象
     * @return
     */
    public static Map<String, Object> objectKeyNullToEmptyByCamel(Object obj) {
        //暂时先用gson转json 然后转成Map对象
        if (ObjectUtilExt.isEmpty(obj)) {
            return new HashMap<String, Object>();
        }
        return JsonUtilExt.json2Map(JsonUtilExt.toJsonString(obj), true);
    }


    /**
     * null 不拷贝
     * @param source
     * @param target
     */
    public static void copyNotNullProperties(Object source, Object target){
        BeanUtil.copyProperties(source,target, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
    }
    /**
     *
     * <p>函数名称：converBean2List        </p>
     * <p>功能说明：列表对象转列表map
     *
     * </p>
     *<p>参数说明：</p>
     * @param listObj
     * @return
     *
     * @date   创建时间：2018年1月17日
     * @author 作者：xds (mailto:xiedeshou@bosssoft.com.cn)
     * @param <T>
     */
    public static <T> List<Map<String,Object>> converBean2List(List<T> listObj){
        List<Map<String,Object>> resultList = new ArrayList<Map<String,Object>>();
        if( listObj == null) {
            return resultList;
        }
        for(Object obj : listObj){
            if(obj == null) {
                continue;
            }
            resultList.add(converBean2Map(obj));
        }
        return resultList;
    }

    /**
     * 对象转map
     * @param obj 源对象
     * @return
     */
    public static Map<String,Object> converBean2Map(Object obj){
        Class<?> type = obj.getClass();
        Map<String,Object> returnMap = new HashMap<String,Object>();
        BeanInfo beanInfo;
        try {
            beanInfo = Introspector.getBeanInfo(type);
            PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
            for (int i = 0; i< propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();
                Method readMethod = descriptor.getReadMethod();
                Object result = readMethod.invoke(obj, new Object[0]);
                if (!propertyName.equals("class")) {
                    if (result != null) {
                        returnMap.put(propertyName, result);
                    } else {
                        if(result instanceof BigDecimal){
                            returnMap.put(propertyName, 0);
                        } else {
                            returnMap.put(propertyName, "");
                        }
                    }
                } else {
                    //bean
                    //	returnMap.put(propertyName, converBean2Map(result));
                }
            }
        } catch (IntrospectionException e) {
            log.error("对象转Map出错:", e);
            throw new RuntimeException("对象转Map出错:",e);
        } catch (InvocationTargetException e) {
            log.error("对象转Map出错:", e);
            throw new RuntimeException("对象转Map出错:",e);
        } catch (IllegalAccessException e) {
            log.error("对象转Map出错:", e);
            throw new RuntimeException("对象转Map出错:",e);
        }
        return returnMap;
    }
}
